package e3dds

import time "gitee.com/ameise84/e3time"

type TimerKind = uint16
type TimerID = uint32
type timerKind32 = uint32

type TimerContext interface {
	Marshal() string        //定时器的上下文在使用时应当注意:上下文不应该是一个具体的对象,而应该是某一个对象的索引方式.
	Unmarshal(string) error //当返回error时,定时器将不会恢复
}

type timerEvent struct {
	Kind timerKind32  `json:"kind"`
	ID   TimerID      `json:"id"`
	Ctx  TimerContext `json:"-"`
}

func (ts *timerEvent) UniqueID() uint64 {
	return uint64(ts.Kind)<<32 | uint64(ts.ID)
}

func newTimerManger() timerManager {
	return timerManager{
		wrap:   time.WrapTimerHandler(32),
		holder: time.NewTimerHolder(),
	}
}

type timerManager struct {
	wrap   *time.HandlerWrap
	holder time.TimerHolder
}

func (ts *timerManager) SetTimer(kind timerKind32, id uint32, dur time.Duration, ctx TimerContext) {
	evt := &timerEvent{
		Kind: kind,
		ID:   id,
		Ctx:  ctx,
	}
	_ = ts.holder.NewTimer(ts.wrap, evt, dur)
}

func (ts *timerManager) SetTimerWithFirst(kind timerKind32, id uint32, doTime time.Time, ctx TimerContext) {
	evt := &timerEvent{
		Kind: kind,
		ID:   id,
		Ctx:  ctx,
	}
	_ = ts.holder.NewTimerWithDoTime(ts.wrap, evt, doTime)
}

func (ts *timerManager) SetTick(kind timerKind32, id uint32, dur time.Duration, repeat int, ctx TimerContext) {
	evt := &timerEvent{
		Kind: kind,
		ID:   id,
		Ctx:  ctx,
	}
	_ = ts.holder.NewTick(ts.wrap, evt, dur, repeat)
}

func (ts *timerManager) SetTickWithFirst(kind timerKind32, id uint32, fireAt time.Time, dur time.Duration, repeat int, ctx TimerContext) {
	evt := &timerEvent{
		Kind: kind,
		ID:   id,
		Ctx:  ctx,
	}
	_ = ts.holder.NewTickWithFirstAt(ts.wrap, evt, fireAt, dur, repeat)
}

func (ts *timerManager) KillTimer(kind timerKind32, id uint32) {
	evt := &timerEvent{
		Kind: kind,
		ID:   id,
	}
	ts.holder.KillTimerWithID(evt.UniqueID())
}
